import backtrader as bt
from .DbOprate import DbOprate

class HighPointReduceStrategy(bt.Strategy):
    params = (
        ('G1', 40),  # 40日周期判断最高价
        ('G2', 20),  # 20日过滤周期
    )
    def log(self, txt, dt=None):
        """记录日志"""
        dt = dt or self.datas[0].datetime.date(0)
        print(f'{dt.isoformat()}, {txt}')
    def __init__(self):
        self.data_close = self.datas[0].close
        
        # 计算40日最高收盘价
        self.hhv_close = bt.indicators.Highest(self.data_close, period=self.p.G1)
        
        # 判断当日是否为40日最高收盘价
        self.x_10 = (self.data_close == self.hhv_close)
        
        # 创建X_10的前一日值用于检测交叉
        self.x_10_prev = self.x_10(-1)
        
        # 检测X_10从1变为0的时刻（创高点后回落）
        self.cross_signal = bt.And(self.x_10_prev == 1, self.x_10 == 0)
        
        # 应用FILTER过滤（简化处理）
        self.filtered_signal = self.cross_signal
        
        # 手动计算bar_since
        self.bar_since_count = 0
        self.x_11 = bt.LineNum(0)
        self.x_16 = bt.LineNum(0)
        
        self.order = None
    def next(self):
        if self.order:
            return
            
        # 更新bar_since计算
        if self.filtered_signal[0]:  # 当前有回落信号
            self.bar_since_count = 0
        else:
            self.bar_since_count += 1
            
        # X_11 = BARSLAST(filtered_signal) + 1
        x_11_value = self.bar_since_count + 1 if self.bar_since_count >= 0 else 0
        self.x_11[0] = x_11_value
        
        # X_16 = X_11 = 1
        x_16_value = 1 if x_11_value == 1 else 0
        self.x_16[0] = x_16_value
        
        # 打印调试信息
        if self.filtered_signal[0]:
            self.log(f'回落信号: X_10={self.x_10[0]}, X_10_prev={self.x_10_prev[0]}')
            
        if x_16_value == 1:
            self.log(f'卖出信号触发! X_11={x_11_value}, CLOSE={self.data_close[0]:.2f}, HHV={self.hhv_close[0]:.2f}')
	        
            result = {
                'strategy': 'HighPointReduceStrategy',
                'stock_code': self.datas[0]._name,
                'op_act': 'sell',
                'op_price': float(self.data_close[0]),
                'op_num': int(size_to_reduce),
                'op_comm': 0.0,
                'op_dt': self.datas[0].datetime.date(0).isoformat(),
                'reason': 'high_point_reduced'
            }
            
            DbOprate.save_result_to_mysql(result)
            
            # 检查是否有持仓
            if self.position:
                self.log('执行卖出操作')
                self.order = self.sell()
            else:
                self.log('无持仓，仅显示信号')

    def notify_order(self, order):
        if order.status in [order.Completed]:
            if order.isbuy():
                self.log(f'买入执行, 价格: {order.executed.price:.2f}')
            elif order.issell():
                self.log(f'卖出执行, 价格: {order.executed.price:.2f}')
            self.order = None
        elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            self.log('订单取消/保证金不足/拒绝')
            self.order = None